package com.lysj.admin.master.auth.service;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lysj.admin.master.CacheManager;
import com.lysj.admin.master.auth.domain.Permission;
import com.lysj.admin.master.auth.domain.Role;
import com.lysj.admin.master.auth.domain.RolePermission;
import com.lysj.admin.master.auth.domain.User;
import com.lysj.admin.master.auth.dto.RoleConditionDTO;
import com.lysj.admin.master.auth.mapper.PermissionMapper;
import com.lysj.admin.master.auth.mapper.RolePermissionMapper;
import com.lysj.admin.master.auth.mapper.RoleMapper;
import com.lysj.admin.master.auth.mapper.UserMapper;
import com.lysj.admin.master.common.cache.RedisKeyEnum;
import com.lysj.admin.master.common.cache.RedisUtil;
import com.lysj.admin.master.common.exception.BaseException;
import com.lysj.admin.master.common.spring.base.BaseEntity;
import com.lysj.admin.master.common.spring.base.BaseRepository;
import com.lysj.admin.master.common.spring.base.BaseService;
import com.lysj.admin.master.common.spring.mpbase.IdEntity;
import com.lysj.admin.master.common.spring.mpbase.MyService;
import com.lysj.admin.master.common.spring.pagination.PageRequestDTO;
import com.lysj.admin.master.common.web.ParamUtil;
import com.lysj.admin.master.common.web.Resp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Created by zk on 2019-12-05 2:23
 * @description
 */
@Slf4j
@Service
@Transactional
public class RoleService extends MyService<RoleMapper, Role> {
    @Resource
    private UserService userService;
    @Resource
    private RolePermissionService rolePermissionService;
    @Resource
    private PermissionService permissionService;
    @Resource
    private AdminAuthentication adminAuthentication;
    @Resource
    private CacheManager cacheManager;
    @Resource
    private RedisUtil redisUtil;

    /**
     * @author zk
     * @date 2019/12/6 11:23
     * @Description 分配角色权限
     */
    @Transactional
    public void editRolePerm(String id, String[] permissionIds) {
        Role role = this.getById(id);
        if (role == null) {
            throw new BaseException(Resp.ResStatus.PARAM_ERROR, "查无此角色");
        }
        //根据角色Id删除所有权限关系
        LambdaQueryWrapper<RolePermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RolePermission::getRoleId, id);
        rolePermissionService.remove(wrapper);
//        rolePermissionMapper.deleteByRoleId(id);
        List<RolePermission> saveData = new ArrayList<>(permissionIds.length);
        //根据Id列表获取所有权限，并构造ID-权限Map
        Map<String, Permission> permissionMap = permissionService.listByIds(Arrays.asList(permissionIds))
                .parallelStream()
                .collect(Collectors.toMap(IdEntity::getId, p -> p));
        for (String permissionId : permissionIds) {
            RolePermission rolePermission = new RolePermission();
            rolePermission.setRoleId(id);
            Permission permission = permissionMap.get(permissionId);
            if (permission == null) {
                throw new BaseException(Resp.ResStatus.PARAM_ERROR, "参数有误，请重新操作");
            }
            rolePermission.setPermissionId(permissionId);
            saveData.add(rolePermission);
        }
        rolePermissionService.saveBatch(saveData);
        //更新权限缓存
        cacheManager.initAdminPermissionRoleCache();
        redisUtil.delete(RedisKeyEnum.ROLE_PERMISSION,id);
    }

    @Transactional
    public void deleteRole(String[] ids) {
        List<String> idList = Arrays.asList(ids);
        if (ParamUtil.isBlank(idList)) {
            return;
        }
//        List<User> userList = userMapper.findByRoleIdIn(Arrays.asList(ids));
        int count = userService.lambdaQuery()
                .in(User::getRoleId, idList)
                .count();
        if (count > 0) {
            throw new BaseException(Resp.ResStatus.PARAM_ERROR, StrUtil.format("存在角色仍有用户在使用，请先全部更改"));
        }
        removeByIds(idList);
        LambdaQueryWrapper<RolePermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(RolePermission::getRoleId, idList);
        rolePermissionService.remove(wrapper);
        cacheManager.initAdminPermissionRoleCache();
    }

    public Page<Role> roleList(RoleConditionDTO condition) {
        Page<Role> roles = pageList(condition);
        Set<String> roleIds = roles.getRecords().parallelStream().map(IdEntity::getId).collect(Collectors.toSet());
//        List<RolePermission> rolePermissions = rolePermissionMapper.findByRoleIdIn(roleIds);
        List<RolePermission> rolePermissions = rolePermissionService.lambdaQuery()
                .in(!ParamUtil.isBlank(roleIds), RolePermission::getRoleId, roleIds)
                .list();
        //角色Id-权限Id列表
        HashMap<String, Set<String>> map = rolePermissions.parallelStream()
                .collect(Collectors.groupingBy(RolePermission::getRoleId, HashMap::new,
                        Collectors.mapping(RolePermission::getPermissionId, Collectors.toSet())));
        for (Role role : roles.getRecords()) {
            Set<String> pIds = map.get(role.getId());
            if (ParamUtil.isBlank(pIds)) {
                role.setPermissionIds(new HashSet<>());
            } else {
                role.setPermissionIds(pIds);
            }
        }
        return roles;


    }


    public  Role  findByIss(String iss){
        return lambdaQuery().eq(Role::getType,iss).one();
    }

}
